//
// Created by ldk on 2020/4/29.
//


#include <iostream>
#include <cstring>

class FakeString {
public:
    explicit FakeString():_str(nullptr){
        std::cout << "FakeString: Default FakeString()" << std::endl;
    }
    explicit FakeString(const char* str): _str(strdup(str)){
        std::cout << "FakeString: " << _str << " from constructor" << std::endl;
    }

    FakeString(FakeString& copy): _str(strdup(copy._str)) {
        std::cout << "FakeString: " << _str << " from copy constructor" << std::endl;
    }

    FakeString(FakeString&& move) noexcept {
        _str = move._str;
        std::cout << "FakeString: " << _str << " from move constructor" << std::endl;
        move._str = nullptr;
    }

    FakeString& operator=(const FakeString& another) {
        if (_str != nullptr){
            free(_str);
        }
        _str = strdup(another._str);
        std::cout << "operator=(FakeString& )" << std::endl;
    }

    FakeString& operator=(FakeString&& another) noexcept {
        if (_str != nullptr){
            free(_str);
        }
        _str = another._str;
        another._str = nullptr;
        std::cout << "operator=(FakeString&& )" << std::endl;
    }

    ~FakeString(){
        std::cout << "~FakeString " << (_str == nullptr ? "NULL" : _str) << std::endl;
        if (_str != nullptr){
            free(_str);
        }
    }

private:
    char* _str;
};

void normalStr() {
    FakeString fakeString("Ldk");
}

FakeString returnObj(){
    return FakeString("return");
}

void copy(){
    FakeString copyConstructor = FakeString("Copy");
    FakeString copyFromReturn = returnObj();
    FakeString&& another = returnObj();
}

void move(){
    FakeString copyMove;
    copyMove = FakeString("tmp obj");
}


int main() {
//    normalStr();
//    copy();
    move();
}